 /**
  * @file       AppInit.java
  * @package    applicaton
  * @brief      Application initialization.
  * 
  * @author     Ondrej Vejtasa, xvejta01@stud.fit.vutbr.cz
  * @date       April 10, 2014
  */

package application;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import java.util.ArrayList;
import java.util.List;

import oracle.adf.model.datacontrols.device.DeviceManager;
import oracle.adf.model.datacontrols.device.DeviceManagerFactory;

import oracle.adfmf.framework.api.AdfmfJavaUtilities;


public class AppInit {
    protected static Connection conn = null;
    private static String LOG = "AppInit: ";
    private static String dbFile = ".adf/META-INF/mobile.sql";
    private static String APPNAME = "EasyTalk";
    private static final String ENCODING = "UTF-8";
    
    public AppInit() {
        super();
    }
    
    /**
     * Connect to the SQLite database.
     * @return Database connection
     * @throws Exception
     */
    public static Connection getConnection() throws Exception {
        if (conn == null) {
            try {
                // ApplicationDirectory returns the private read-write sandbox area
                // of the mobile device's file system that this application can access.
                // This is where the database is created
                String Dir = AdfmfJavaUtilities.getDirectoryPathRoot(AdfmfJavaUtilities.ApplicationDirectory);
                String connStr = "jdbc:sqlite:" + Dir + "/mobile.db";
                

                // If the database does not exist, a new database is automatically
                // created when the SQLite JDBC connection is created
                conn = new SQLite.JDBCDataSource(connStr).getConnection();
            } catch (SQLException e) {
                System.err.println("DBConnectionFactory: " + "getConnection() Exception " + e.getMessage());
                e.printStackTrace();
            }
        }
        return conn;
    }
    
    /**
     * This method will read the sql file and
     * commit the sql statements to the SQLite DB.
     */
    public void initDB() {
        
        
        try {            
            // Since the SQL script has been packaged as a resource within
            // the application, the getResourceAsStream method is used
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            InputStream is = cl.getResourceAsStream(dbFile);

            if (is == null) {
                System.err.println(LOG + "SQL DB FILE could not look up: " + dbFile);
                return;
            }

            // load database file via encoding
            BufferedReader bReader = new BufferedReader(new InputStreamReader(is, ENCODING));
            List stmts = new ArrayList();
            String strstmt = "";
            String ln = bReader.readLine();

            // The while loop iterates over all the lines in the SQL script,
            // assembling them into valid SQL statements and executing them as
            // a terminating semicolon is encountered
            while (ln != null) {
                // Skipping blank lines, comments, and COMMIT statements
                if (ln.startsWith("REM") || ln.startsWith("COMMIT")) {
                    ln = bReader.readLine();
                    continue;
                }
                
                strstmt = strstmt + ln;
                if (strstmt.endsWith(";")) {
                    stmts.add(strstmt);
                    strstmt = "";
                    ln = bReader.readLine();
                    continue;
                }
                ln = bReader.readLine();
            }

            // To improve performance, the statements are executed
            // one at a time in the context of a single transaction
            getConnection().setAutoCommit(false);
            for (int i = 0; i < stmts.size(); i++) {
                Statement pStmt = getConnection().createStatement();
                pStmt.executeUpdate((String)stmts.get(i));
                System.err.println(LOG + (String)stmts.get(i));
            }
            
            getConnection().commit();
            
        } catch (SQLException e) {
            System.err.println(LOG + "InitDB() " + e.getMessage());
            
        } catch (Exception e) {
            System.err.println(LOG + "InitDB() " + e.getMessage());
        }
    }
    
    /**
     * Createapplication directory by operation system. 
     * ADF Mobile BUG!! Don't call this methot during start an application, 
     * ADF Mobile don't return operation system identifiers!!
     * @param type type of directory, supported are audio, draw and image
     * @return path to directory
     */
    public String createAppDirectory(String type) {
        DeviceManager device = DeviceManagerFactory.getDeviceManager();
        String dir = AdfmfJavaUtilities.getDirectoryPathRoot(AdfmfJavaUtilities.DownloadDirectory);
        if (device.getOs().equals("Android")) {
            dir += "/" + APPNAME + "/";
        } else if (device.getOs().equals("iOS")) {
            dir += "/";
        }

        String fPath = dir;
        File etDir = new File(fPath);
        if (!etDir.exists()) {
            boolean result = etDir.mkdir();  
            if(!result) {    
                System.out.println("DIR create FAILED " + fPath);  
             }
        }
        fPath += type + "/";
        File d = new File(fPath);
        if (!d.exists()) {
            boolean result = d.mkdir();  
            if(!result) {    
                System.out.println("DIR create FAILED " + fPath);  
            }
        }
            
        return fPath;
    }
    
}
